package service

import (
	"context"
	"fmt"
	"log"
	"os"

	dataModel "assistant/biz/model"

	"github.com/cloudwego/eino-ext/components/model/openai"
	"github.com/cloudwego/eino/components/tool"
	"github.com/cloudwego/eino/compose"
	"github.com/cloudwego/eino/flow/agent/react"
	"github.com/cloudwego/eino/schema"

	"github.com/google/uuid"
)

var agent *react.Agent

// InitAgent initializes the ReAct agent with OpenAI ChatModel and tools.
func InitAgent(ctx context.Context) error {

	openAIAPIKey := os.Getenv("API_KEY")
	modelName := os.Getenv("MODEL")
	baseUrl := os.Getenv("BASE_URL")
	chatModel, err := openai.NewChatModel(ctx, &openai.ChatModelConfig{
		Model:   modelName,
		APIKey:  openAIAPIKey,
		BaseURL: baseUrl,
	})
	if err != nil {
		log.Printf("[InitAgent] Failed to create chat model with model=%s: %v", modelName, err)
		return err
	}

	toolConfig := compose.ToolsNodeConfig{
		Tools: []tool.BaseTool{
			GetProductListTool(),
			GetProductDetailTool(),
			SearchProductTool(),
			AddToCartTool(),
		},
	}

	agentInstance, err := react.NewAgent(ctx, &react.AgentConfig{
		Model:       chatModel,
		ToolsConfig: toolConfig,
		MaxStep:     5, // Limit agent steps for safety and cost control
		MessageModifier: func(ctx context.Context, messages []*schema.Message) []*schema.Message {
			// 在 MessageModifier 中应用系统提示词
			systemPrompt := GetSystemPrompt() // 从 prompt.go 获取系统提示词
			modifiedMessages := []*schema.Message{systemPrompt}
			modifiedMessages = append(modifiedMessages, messages...)
			return modifiedMessages
		},
	})
	if err != nil {
		log.Printf("[InitAgent] Failed to create agent instance: %v", err)
		return err
	}
	agent = agentInstance
	log.Println("[InitAgent] Agent initialized successfully") // Add log to indicate successful initialization
	return nil
}

// StartConversationService starts a new conversation with the AI agent.
func StartConversationService(ctx context.Context, req *dataModel.StartConversationRequest) (*dataModel.AIResponseMessage, error) {
	if agent == nil {
		log.Printf("[StartConversation] Agent not initialized, attempting to initialize")
		if err := InitAgent(ctx); err != nil {
			log.Printf("[StartConversation] Failed to initialize agent: %v", err)
			return nil, err
		}
	}

	// 创建新的会话ID
	conversationId := fmt.Sprintf("%d", req.UserId)[:4] + uuid.New().String()

	// 获取会话管理器实例
	cm := GetConversationManager()

	// 添加用户消息到历史记录
	cm.AddMessage(conversationId, "user", req.Context)

	// 获取历史消息的schema.Message数组
	messages := cm.ToSchemaMessages(conversationId)

	// 生成回复
	resp, err := agent.Generate(ctx, messages)
	if err != nil {
		log.Printf("[StartConversation] Failed to generate response for user=%d: %v", req.UserId, err)
		return nil, err
	}

	log.Printf("[StartConversation] Successfully generated response for conversation=%s, user=%d", conversationId, req.UserId)

	// 添加助手回复到历史记录
	cm.AddMessage(conversationId, "assistant", resp.Content)

	aiResp := &dataModel.AIResponseMessage{
		ConversationId: conversationId,
		Content:        resp.Content,
	}

	return aiResp, nil
}

// SendUserMessageService sends a user message to the AI agent and returns the AI response.
func SendUserMessageService(ctx context.Context, req *dataModel.UserMessageRequest) (*dataModel.AIResponseMessage, error) {
	if agent == nil {
		log.Printf("[SendUserMessage] Agent not initialized, attempting to initialize for conversation=%s", req.ConversationId)
		if err := InitAgent(ctx); err != nil {
			log.Printf("[SendUserMessage] Failed to initialize agent for conversation=%s: %v", req.ConversationId, err)
			return nil, err
		}
	}

	// 获取会话管理器实例
	cm := GetConversationManager()

	// 添加用户消息到历史记录
	cm.AddMessage(req.ConversationId, "user", req.UserMessage)

	// 获取历史消息的schema.Message数组
	messages := cm.ToSchemaMessages(req.ConversationId)

	// 生成回复
	resp, err := agent.Generate(ctx, messages)
	if err != nil {
		log.Printf("[SendUserMessage] Failed to generate response for conversation=%s: %v", req.ConversationId, err)
		return nil, err
	}

	log.Printf("[SendUserMessage] Successfully generated response for conversation=%s", req.ConversationId)

	// 添加助手回复到历史记录
	cm.AddMessage(req.ConversationId, "assistant", resp.Content)

	aiResp := &dataModel.AIResponseMessage{
		ConversationId: req.ConversationId,
		Content:        resp.Content,
	}

	return aiResp, nil
}
